﻿using System;
using System.Reflection;
using System.Linq.Expressions;

namespace Arch.Common.Reflection
{
    public static class MethodInfoExtentionsTest
    {
        public static Action<object, T> Compile<T>(this MethodInfo methodInfo)
        {
            if (!methodInfo.IsPublic) return null;

            ParameterExpression instanceParameter = Expression.Parameter(typeof(object), "method");
            ParameterExpression valueArgument = Expression.Parameter(typeof(T), "argument");

            MethodCallExpression callExpression = Expression.Call(
                                            Expression.ConvertChecked(instanceParameter, methodInfo.DeclaringType),
                                            methodInfo,
                                            Expression.Convert(valueArgument, typeof(T)));
            return Expression.Lambda<Action<object, T>>(callExpression, instanceParameter, valueArgument).Compile();
        }

        public static Action<object> Compile(this MethodInfo methodInfo)
        {
            ParameterExpression instanceParameter = Expression.Parameter(typeof(object), "method");
            MethodCallExpression callExpression = Expression.Call(
                                            Expression.ConvertChecked(instanceParameter, methodInfo.DeclaringType),
                                            methodInfo);
            return Expression.Lambda<Action<object>>(callExpression, instanceParameter).Compile();
        }
    }
}
